require("stategraphs/commonstates")

local events = {
    CommonHandlers.OnLocomote(false, true),
    CommonHandlers.OnHop(),
    CommonHandlers.OnSink(),
    CommonHandlers.OnFallInVoid(),
    EventHandler("dotrade", function(inst, data)
        if not inst.sg:HasStateTag("busy") then
            inst.sg.statemem.keeprevealed = true
            inst.sg:GoToState("dotrade", data)
        end
    end),
    EventHandler("arrive", function(inst)
        inst.sg:GoToState("arrive")
    end),
}

local states = {
    State {
        name = "idle",
        tags = { "idle", "canrotate" },

        onenter = function(inst)
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("idle_loop", true)
        end,

        onupdate = function(inst)
            if not inst:IsAsleep() then
                if inst.sg.mem.trading then
                    inst.sg:GoToState("trading_start")
                elseif inst:HasStock() and inst:IsNearPlayer(TUNING.RESEARCH_MACHINE_DIST, true) then
                    inst:EnablePrototyper(true)
                    inst.sg:GoToState("trading_start")
                end
            end
        end,
    },

    State {
        name = "walk_start",
        tags = { "moving", "canrotate" },

        onenter = function(inst)
            inst.AnimState:PlayAnimation("walk_pre")
        end,

        events = {
            EventHandler("animover", function(inst)
                if inst.sg.mem.trading then
                    inst.sg:GoToState("walk_stop")
                else
                    inst.sg:GoToState("walk")
                end
            end),
        },
    },

    State {
        name = "walk",
        tags = { "moving", "canrotate" },

        onenter = function(inst)
            inst.components.locomotor:WalkForward()
            inst.AnimState:PlayAnimation("walk_loop")
        end,
        onupdate = function(inst)
            if inst.sg.mem.trading then
                inst.sg:GoToState("walk_stop")
            end
        end,
        onexit = function(inst)
        end,
        timeline = {
            TimeEvent(1 * FRAMES, function(inst) PlayFootstep(inst) end),
            TimeEvent(13 * FRAMES, function(inst) PlayFootstep(inst) end),
        },
        events = {
            EventHandler("animover", function(inst)
                if inst.sg.mem.trading then
                    inst.sg:GoToState("walk_stop")
                else
                    inst.sg:GoToState("walk")
                end
            end),
        },
    },

    State {
        name = "walk_stop",
        tags = { "canrotate" },

        onenter = function(inst)
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("walk_pst")
        end,

        events = {
            EventHandler("animover", function(inst)
                if inst.sg.mem.trading then
                    inst.sg:GoToState("trading_start")
                else
                    inst.sg:GoToState("idle")
                end
            end),
        },
    },

    State {
        name = "trading_start",
        tags = { "canrotate", "revealed" },

        onenter = function(inst)
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("emote_hat")
            inst:SetRevealed(true)
        end,
        events = {
            EventHandler("animover", function(inst)
                if inst.AnimState:IsCurrentAnimation("emote_hat") then
                    if inst.sg.mem.trading then
                        inst.AnimState:PlayAnimation("pig_pickup")
                    else
                        inst.AnimState:PlayAnimation("emote_bow")
                    end
                elseif inst.AnimState:IsCurrentAnimation("pig_pickup") then
                    inst.sg.statemem.keeprevealed = true
                    if inst.sg.mem.trading then
                        inst.sg:GoToState("trading")
                    else
                        inst.sg:GoToState("trading_stop")
                    end
                else
                    inst.sg:GoToState("idle")
                end
            end),
        },
        onexit = function(inst)
            if not inst.sg.statemem.keeprevealed then
                inst:SetRevealed(false)
            end
        end,
    },
    State {
        name = "trading",
        tags = { "canrotate", "revealed" },

        onenter = function(inst, data)
            if data == nil or not data.repeating then
                inst:TryChatter("BBOY_PIGGY_HI_STARTTRADING", math.random(#STRINGS.BBOY_PIGGY_HI_STARTTRADING), 1.5)
            end
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("idle_loop")
            inst:SetRevealed(true)
        end,
        onupdate = function(inst)
            if not inst.sg.mem.trading then
                inst.sg:GoToState("trading_stop")
            end
        end,
        events = {
            EventHandler("animover", function(inst)
                inst.sg.statemem.keeprevealed = true
                if inst.sg.mem.trading then
                    inst.sg:GoToState("trading", { repeating = true, })
                else
                    inst.sg:GoToState("trading_stop")
                end
            end),
        },
        onexit = function(inst)
            if not inst.sg.statemem.keeprevealed then
                inst:SetRevealed(false)
            end
        end,
    },
    State {
        name = "trading_stop",
        tags = { "canrotate", "revealed" },

        onenter = function(inst)
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("idle_loop")
            if inst.sg.mem.didtrade then
                inst:TryChatter("BBOY_PIGGY_HI_ENDTRADING_MADETRADE", math.random(#STRINGS.BBOY_PIGGY_HI_ENDTRADING_MADETRADE), 1.5)
                inst.sg.mem.didtrade = nil
            else
                inst:TryChatter("BBOY_PIGGY_HI_ENDTRADING_NOTRADES", math.random(#STRINGS.BBOY_PIGGY_HI_ENDTRADING_NOTRADES), 1.5)
            end
            inst:SetRevealed(true)
        end,
        events = {
            EventHandler("animover", function(inst)
                if inst.AnimState:IsCurrentAnimation("idle_loop") then
                    if inst.sg.mem.trading then
                        inst.AnimState:PlayAnimation("pig_pickup")
                    else
                        inst.AnimState:PlayAnimation("emote_bow")
                    end
                elseif inst.AnimState:IsCurrentAnimation("pig_pickup") then
                    inst.sg.statemem.keeprevealed = true
                    if inst.sg.mem.trading then
                        inst.sg:GoToState("trading")
                    else
                        inst.sg:GoToState("trading_stop")
                    end
                else
                    inst.sg:GoToState("idle")
                end
            end),
        },
        onexit = function(inst)
            if not inst.sg.statemem.keeprevealed then
                inst:SetRevealed(false)
            end
        end,
    },
    State {
        name = "dotrade",
        tags = { "busy", "revealed" },
        onenter = function(inst, data)
            inst.Physics:Stop()
            inst.AnimState:PlayAnimation("interact")
            if data and data.no_stock then
                inst:DoChatter("BBOY_PIGGY_HI_OUTOFSTOCK_FROMTRADES", math.random(#STRINGS.BBOY_PIGGY_HI_OUTOFSTOCK_FROMTRADES), 15)
            else
                if not inst.sg.mem.didtrade then
                    inst:DoChatter("BBOY_PIGGY_HI_DOTRADE", math.random(#STRINGS.BBOY_PIGGY_HI_DOTRADE), 1.5)
                else
                    inst:TryChatter("BBOY_PIGGY_HI_DOTRADE", math.random(#STRINGS.BBOY_PIGGY_HI_DOTRADE), 1.5)
                end
            end
            inst:SetRevealed(true)
        end,
        events = {
            EventHandler("animover", function(inst)
                inst.sg.statemem.keeprevealed = true
                inst.sg:GoToState("trading")
            end),
        },
        onexit = function(inst)
            if not inst.sg.statemem.keeprevealed then
                inst:SetRevealed(false)
            end
        end,
    },

    State {
        name = "talking",
        tags = { "canrotate", "revealed" },

        onenter = function(inst, already_talking)
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("idle_loop")
            inst:SetRevealed(true)
        end,

        events = {
            EventHandler("animover", function(inst)
                inst.sg.statemem.keep_talking = true
                inst.sg.statemem.keeprevealed = true
                inst.sg:GoToState("talking", true)
            end),
        },

        onexit = function(inst)
            if not inst.sg.statemem.keep_talking then
            end
            if not inst.sg.statemem.keeprevealed then
                inst:SetRevealed(false)
            end
        end,
    },

    State {
        name = "teleport",
        tags = { "busy" },

        onenter = function(inst)
            inst.components.talker:ShutUp()
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("hungry")
        end,

        timeline = {
            FrameEvent(24, function(inst)
                inst.DynamicShadow:Enable(false)
                inst.sg:AddStateTag("invisible")
                inst:AddTag("NOCLICK")
            end),
        },

        onexit = function(inst)
            inst.DynamicShadow:Enable(true)
            inst:RemoveTag("NOCLICK")
        end,

        events = {
            EventHandler("animover", function(inst)
                if inst.HiddenActionFn then
                    inst:HiddenActionFn()
                else
                    inst.sg:GoToState("arrive")
                end
            end),
            EventHandler("arrive", function(inst)
                if inst:IsAsleep() then
                    inst.sg:GoToState("idle")
                    return true
                end
            end),
        },
    },

    State {
        name = "arrive",
        tags = { "busy", "invisible" },

        onenter = function(inst)
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("hungry")
            inst:AddTag("NOCLICK")
        end,

        timeline = {
            FrameEvent(2, function(inst)
                inst:RemoveTag("NOCLICK")
                inst.sg:RemoveStateTag("invisible")
            end),
        },

        onexit = function(inst)
            inst:RemoveTag("NOCLICK")
        end,

        events = {
            EventHandler("animover", function(inst)
                inst.sg:GoToState("idle")
            end),
        },
    },

    State {
        name = "leave",

        onenter = function(inst)
            inst.components.talker:ShutUp()
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("hungry")
        end,

        events = {
            EventHandler("animover", function(inst)
                local x, y, z = inst.Transform:GetWorldPosition()
                inst:Remove()
                local fx = SpawnPrefab("collapse_small")
                fx.Transform:SetPosition(x, y, z)
            end),
        },
    },

    State {
        name = "hiding",
    },
}

CommonStates.AddSinkAndWashAshoreStates(states)
CommonStates.AddVoidFallStates(states)

return StateGraph("bboy_piggy_hi", states, events, "idle")
